﻿const cloud = require("wx-server-sdk");

cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV });

const db = cloud.database();

const allowedStatus = new Set(["Draft", "Published", "Withdraw"]);

const normalizeString = value =>
  typeof value === "string" ? value.trim() : "";

const toDateValue = value => {
  if (!value) {
    return null;
  }
  if (value instanceof Date) {
    return Number.isNaN(value.getTime()) ? null : value;
  }
  if (typeof value === "object" && value.$date) {
    return toDateValue(value.$date);
  }
  let normalized = value;
  if (typeof value === "string") {
    normalized = value.trim();
    if (!normalized) {
      return null;
    }
    if (/^\d+$/.test(normalized)) {
      const timestamp = Number(normalized);
      return Number.isNaN(timestamp) ? null : new Date(timestamp);
    }
    normalized = normalized.replace(/\//g, "-");
    if (/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}(:\d{2})?$/.test(normalized)) {
      normalized = normalized.replace(" ", "T");
    }
    if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}$/.test(normalized)) {
      normalized = `${normalized}:00`;
    }
    if (/^\d{4}-\d{2}-\d{2}$/.test(normalized)) {
      normalized = `${normalized}T00:00:00`;
    }
  }
  const date = new Date(normalized);
  return Number.isNaN(date.getTime()) ? null : date;
};

const combineDateTime = (datePart, timePart) => {
  if (!datePart || !timePart) {
    return "";
  }
  return `${datePart} ${timePart}`;
};

const validateForPublish = ({
  activityName,
  activityLocation,
  registrationStartTime,
  registrationEndTime,
  activityDetails,
  activityImageURL,
  activityRequirements,
  activityGroups,
  activityFields
}) => {
  if (!normalizeString(activityName)) {
    return "请填写活动名称";
  }
  if (!normalizeString(activityLocation)) {
    return "请填写活动地点";
  }
  const start = toDateValue(registrationStartTime);
  const end = toDateValue(registrationEndTime);
  if (!start || !end) {
    return "报名时间格式不正确";
  }
  if (start.getTime() >= end.getTime()) {
    return "报名结束时间需晚于开始时间";
  }
  if (!normalizeString(activityDetails)) {
    return "请填写活动介绍";
  }
  if (!normalizeString(activityImageURL)) {
    return "请上传活动图片";
  }
  if (!normalizeString(activityRequirements)) {
    return "请填写活动要求";
  }
  if (!Array.isArray(activityGroups) || activityGroups.length === 0) {
    return "请至少保留一个分组";
  }
  const groupNames = new Set();
  for (let i = 0; i < activityGroups.length; i += 1) {
    const group = activityGroups[i] || {};
    const name = normalizeString(group.groupName);
    if (!name) {
      return `请填写第 ${i + 1} 个分组名称`;
    }
    if (groupNames.has(name)) {
      return `分组名称重复：${name}`;
    }
    groupNames.add(name);
    const gStart = toDateValue(group.groupStartTime || combineDateTime(group.groupStartTimeDate, group.groupStartTimeClock));
    const gEnd = toDateValue(group.groupEndTime || combineDateTime(group.groupEndTimeDate, group.groupEndTimeClock));
    if (!gStart || !gEnd) {
      return `第 ${i + 1} 个分组时间格式不正确`;
    }
    if (gStart.getTime() >= gEnd.getTime()) {
      return `第 ${i + 1} 个分组结束时间需晚于开始时间`;
    }
    const count = Number(group.groupRegistrationCount);
    if (!Number.isInteger(count) || count <= 0) {
      return `第 ${i + 1} 个分组报名人数上限不正确`;
    }
  }
  if (Array.isArray(activityFields) && activityFields.length > 0) {
    const fieldNames = new Set();
    for (let i = 0; i < activityFields.length; i += 1) {
      const field = activityFields[i] || {};
      const fieldName = normalizeString(field.fieldName);
      if (!fieldName) {
        return `请填写第 ${i + 1} 个报名问题名称`;
      }
      if (fieldNames.has(fieldName)) {
        return `报名问题重复：${fieldName}`;
      }
      fieldNames.add(fieldName);
    }
  }
  return "";
};

const createActivity = async event => {
  const wxContext = cloud.getWXContext();
  const openID = wxContext.OPENID;

  if (!openID) {
    return { success: false, error: "未获取到用户信息" };
  }

  const activityName = normalizeString(event && event.activityName);
  const activityLocation = normalizeString(event && event.activityLocation);
  const activityDetails = normalizeString(event && event.activityDetails);
  const activityImageURL = normalizeString(event && event.activityImageURL);
  const activityRequirements = normalizeString(event && event.activityRequirements);
  const registrationStartTime = event && event.registrationStartTime;
  const registrationEndTime = event && event.registrationEndTime;
  const activityStatus = normalizeString(event && event.activityStatus) || "Draft";
  const activityGroups = Array.isArray(event && event.activityGroups)
    ? event.activityGroups
    : [];
  const activityFields = Array.isArray(event && event.activityFields)
    ? event.activityFields
    : [];

  if (!allowedStatus.has(activityStatus)) {
    return { success: false, error: "状态不合法" };
  }

  if (activityStatus === "Published") {
    const validationMessage = validateForPublish({
      activityName,
      activityLocation,
      registrationStartTime,
      registrationEndTime,
      activityDetails,
      activityImageURL,
      activityRequirements,
      activityGroups,
      activityFields
    });
    if (validationMessage) {
      return { success: false, error: validationMessage };
    }
  }

  const startDate = toDateValue(registrationStartTime);
  const endDate = toDateValue(registrationEndTime);

  try {
    const result = await db.runTransaction(async transaction => {
      const activityRes = await transaction.collection("Activity_Information").add({
        data: {
          PublisherOpenID: openID,
          ActivityName: activityName,
          ActivityLocation: activityLocation,
          RegistrationStartTime: startDate,
          RegistrationEndTime: endDate,
          ActivityDetails: activityDetails,
          ActivityImageURL: activityImageURL,
          ActivityRequirements: activityRequirements,
          ActivityPublishTime: activityStatus === "Published" ? db.serverDate() : null,
          Status: activityStatus
        }
      });

      const activityID = activityRes._id;

      for (const group of activityGroups) {
        const start = toDateValue(group.groupStartTime || combineDateTime(group.groupStartTimeDate, group.groupStartTimeClock));
        const end = toDateValue(group.groupEndTime || combineDateTime(group.groupEndTimeDate, group.groupEndTimeClock));
        await transaction.collection("Activity_Group_Information").add({
          data: {
            ActivityID: activityID,
            GroupName: normalizeString(group.groupName),
            GroupStartTime: start,
            GroupEndTime: end,
            GroupRegistrationCount: Number.isInteger(Number(group.groupRegistrationCount))
              ? Number(group.groupRegistrationCount)
              : 0,
            CheckInStartTime: null,
            CheckInCodeOrURL: "",
            IsCheckInActive: false,
            CheckOutStartTime: null,
            CheckOutCodeOrURL: "",
            IsCheckOutActive: false,
            Remark: normalizeString(group.remark)
          }
        });
      }

      for (const field of activityFields) {
        await transaction.collection("Activity_Registration_Information_Fields").add({
          data: {
            ActivityID: activityID,
            FieldName: normalizeString(field.fieldName),
            IsOptional: !!field.isOptional
          }
        });
      }

      return {
        success: true,
        activityID
      };
    });

    return result;
  } catch (error) {
    return {
      success: false,
      error: error.message || "数据库操作失败"
    };
  }
};

exports.main = async (event, context) => {
  return createActivity(event, context);
};
